Packages

library(here)
package 㤼㸱here㤼㸲 was built under R version 3.4.3here() starts at C:/Users/jrl/Documents/casestudy-mapping-with-r

Data

ucsfi <- read_sf("data/ucsfi.shp")  # %>% `st_crs<-`(3857)  # 3857 is Web mercator
brazil0 <- read_sf("data/BRA_adm/BRA_adm0.shp")

Projection

In the above code chunk projection is commented out because tmap appears to work beset without the projection assigned. We’ll do that later. assigned with st_crs() using a somewhat non-standard syntax. However, It seemed to be the only way I could add a projection to this particular shapefile. Below are some other syntax examples that have worked for me with other shapefiles. Of course there are various ways to add projection and since this is R, there’s more than one way to accomplish the goal.

sf::st_crs(3857)
sf::st_transform(3857)
ggplot2::coord_sf(crs = 3857)   # must use the development version of ggplot2

Notes on Projection

From Brazillian CRS

  • 4989
  • 4674
  • 5527
  • 4618

Check Projection

st_crs(ucsfi)
Coordinate Reference System: NA
print("ucsfi above ^^^  --------- brazil0 below")
[1] "ucsfi above ^^^  --------- brazil0 below"
st_crs(brazil0)
Coordinate Reference System:
  EPSG: 4326 
  proj4string: "+proj=longlat +datum=WGS84 +no_defs"
# or check the projection for an individual polygon ...
# ucsfi$geometry %>% head(1) 

Data Preview

as_tibble(ucsfi)
Simple feature collection with 147 features and 13 fields
geometry type:  MULTIPOLYGON
dimension:      XY
bbox:           xmin: -73.99068 ymin: -32.92342 xmax: -32.35011 ymax: 5.272257
epsg (SRID):    NA
proj4string:    NA

Wrangle Data

I want to use a numeric data type as my “fill”

ucsfi <- ucsfi %>% 
  mutate(GID7 = as.numeric(GID7))

ggplot

ucsfi %>% 
  mutate(ANO_CRIA6 = as.numeric(ANO_CRIA6)) %>% 
  ggplot() +
  geom_sf(aes(fill = ANO_CRIA6, color = ANO_CRIA6)) 
NAs introduced by coercion

Note different lat/long representations

i.e. different CRS

brazil0 %>% 
  ggplot() +
  geom_sf(aes()) 

ggplot() +
  geom_sf(aes(), data = brazil0)

ggplot() +
  geom_sf(aes(), data = ucsfi)

Harmonize CRS

#`st_crs<-`(ucsfi)
st_crs(ucsfi)
Coordinate Reference System: NA
st_crs(brazil0)
Coordinate Reference System:
  EPSG: 4326 
  proj4string: "+proj=longlat +datum=WGS84 +no_defs"

Hardcode the crs

with some very funky notation

`st_crs`<-(4326)

ucsfi <- ucsfi %>% 
  `st_crs<-`(4326)

Verify CRS Assignment

#`st_crs<-`(ucsfi)
st_crs(ucsfi)
Coordinate Reference System:
  EPSG: 4326 
  proj4string: "+proj=longlat +datum=WGS84 +no_defs"
st_crs(brazil0)
Coordinate Reference System:
  EPSG: 4326 
  proj4string: "+proj=longlat +datum=WGS84 +no_defs"

TEST with New CRS

Note the same CRS represented by the same lat/lon

ggplot() +
  geom_sf(aes(), data = ucsfi)

ggplot() +
  geom_sf(aes(), data = brazil0)

Layer the Two maps

ggplot() +
  geom_sf(aes(), data = brazil0) +
  geom_sf(aes(fill = GID7, colors = GID7), data = ucsfi) 
Ignoring unknown aesthetics: colors

Convert back to sp

Because you might prefer mapping ggplot using geom_polygon

class(ucsfi)
[1] "sf"         "tbl_df"     "tbl"        "data.frame"
class(brazil0)
[1] "sf"         "tbl_df"     "tbl"        "data.frame"

Convert from sf to sp

uc_sp <- as(ucsfi, "Spatial")
bz_sp <- as(ucsfi, "Spatial")
class(uc_sp)
[1] "SpatialPolygonsDataFrame"
attr(,"package")
[1] "sp"
class(bz_sp)
[1] "SpatialPolygonsDataFrame"
attr(,"package")
[1] "sp"

Remove Lat/Lon Lines

ggplot() +
  geom_sf(aes(), data = brazil0) +
  geom_sf(aes(fill = GID7, colors = GID7), data = ucsfi) +
  theme(legend.position = "bottom", 
        panel.background = element_rect(fill = "transparent"), 
        panel.grid.major = element_line(color = "transparent"), 
        axis.text.x = element_blank(), 
        axis.text.y = element_blank(), 
        axis.ticks = element_blank()) + 
  ggtitle("Coolio Brazil Map Title") + 
  ylab("South to North") 
Ignoring unknown aesthetics: colors

Save It

ggsave(here("outfile","cool_map.png"))
Saving 7 x 7 in image
LS0tDQp0aXRsZTogIlNvbHV0aW9ucyINCmF1dGhvcjogIkpvaG4gTGl0dGxlIg0KZGF0ZTogImBSIFN5cy5EYXRlKClgIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KIyMgUGFja2FnZXMNCg0KYGBge3J9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoc2YpDQpsaWJyYXJ5KGhlcmUpDQpgYGANCg0KIyMgRGF0YQ0KDQpgYGB7cn0NCnVjc2ZpIDwtIHJlYWRfc2YoImRhdGEvdWNzZmkuc2hwIikgICMgJT4lIGBzdF9jcnM8LWAoMzg1NykgICMgMzg1NyBpcyBXZWIgbWVyY2F0b3INCmJyYXppbDAgPC0gcmVhZF9zZigiZGF0YS9CUkFfYWRtL0JSQV9hZG0wLnNocCIpDQpgYGANCg0KDQojIyBQcm9qZWN0aW9uDQoNCkluIHRoZSBhYm92ZSBjb2RlIGNodW5rIHByb2plY3Rpb24gaXMgY29tbWVudGVkIG91dCBiZWNhdXNlIHRtYXAgYXBwZWFycyB0byB3b3JrIGJlc2V0ICoqd2l0aG91dCoqIHRoZSBwcm9qZWN0aW9uIGFzc2lnbmVkLiAgV2UnbGwgZG8gdGhhdCBsYXRlci4gYXNzaWduZWQgd2l0aCBgc3RfY3JzKClgIHVzaW5nIGEgc29tZXdoYXQgbm9uLXN0YW5kYXJkIHN5bnRheC4gSG93ZXZlciwgSXQgc2VlbWVkIHRvIGJlIHRoZSBvbmx5IHdheSBJIGNvdWxkIGFkZCBhIHByb2plY3Rpb24gdG8gdGhpcyBwYXJ0aWN1bGFyIHNoYXBlZmlsZS4gIEJlbG93IGFyZSBzb21lIG90aGVyIHN5bnRheCBleGFtcGxlcyB0aGF0IGhhdmUgd29ya2VkIGZvciBtZSB3aXRoIG90aGVyIHNoYXBlZmlsZXMuICBPZiBjb3Vyc2UgdGhlcmUgYXJlIHZhcmlvdXMgd2F5cyB0byBhZGQgcHJvamVjdGlvbiBhbmQgc2luY2UgdGhpcyBpcyBSLCB0aGVyZSdzIG1vcmUgdGhhbiBvbmUgd2F5IHRvIGFjY29tcGxpc2ggdGhlIGdvYWwuDQoNCmBgYHt9DQpzZjo6c3RfY3JzKDM4NTcpDQpzZjo6c3RfdHJhbnNmb3JtKDM4NTcpDQpnZ3Bsb3QyOjpjb29yZF9zZihjcnMgPSAzODU3KSAgICMgbXVzdCB1c2UgdGhlIGRldmVsb3BtZW50IHZlcnNpb24gb2YgZ2dwbG90Mg0KDQpgYGANCg0KIyMjIE5vdGVzIG9uIFByb2plY3Rpb24NCg0KRnJvbSBbQnJhemlsbGlhbiBDUlNdKGh0dHBzOi8vd2lraS5vc2dlby5vcmcvd2lraS9CcmF6aWxpYW5fQ29vcmRpbmF0ZV9SZWZlcmVuY2VfU3lzdGVtcykNCg0KLSA0OTg5IA0KLSA0Njc0DQotIDU1MjcNCi0gNDYxOA0KDQoNCiMjIyBDaGVjayBQcm9qZWN0aW9uDQoNCmBgYHtyfQ0Kc3RfY3JzKHVjc2ZpKQ0KcHJpbnQoInVjc2ZpIGFib3ZlIF5eXiAgLS0tLS0tLS0tIGJyYXppbDAgYmVsb3ciKQ0Kc3RfY3JzKGJyYXppbDApDQoNCiMgb3IgY2hlY2sgdGhlIHByb2plY3Rpb24gZm9yIGFuIGluZGl2aWR1YWwgcG9seWdvbiAuLi4NCiMgdWNzZmkkZ2VvbWV0cnkgJT4lIGhlYWQoMSkgDQpgYGANCg0KIyMgRGF0YSBQcmV2aWV3DQoNCmBgYHtyfQ0KYXNfdGliYmxlKHVjc2ZpKQ0KYGBgDQoNCiMjIyBXcmFuZ2xlIERhdGENCg0KSSB3YW50IHRvIHVzZSBhIG51bWVyaWMgZGF0YSB0eXBlIGFzIG15ICJmaWxsIg0KDQpgYGB7cn0NCnVjc2ZpIDwtIHVjc2ZpICU+JSANCiAgbXV0YXRlKEdJRDcgPSBhcy5udW1lcmljKEdJRDcpKQ0KYGBgDQoNCg0KIyMgZ2dwbG90DQoNCmBgYHtyfQ0KdWNzZmkgJT4lIA0KICBtdXRhdGUoQU5PX0NSSUE2ID0gYXMubnVtZXJpYyhBTk9fQ1JJQTYpKSAlPiUgDQogIGdncGxvdCgpICsNCiAgZ2VvbV9zZihhZXMoZmlsbCA9IEFOT19DUklBNiwgY29sb3IgPSBBTk9fQ1JJQTYpKSANCmBgYA0KDQojIyBOb3RlIGRpZmZlcmVudCBsYXQvbG9uZyByZXByZXNlbnRhdGlvbnMNCg0KaS5lLiBkaWZmZXJlbnQgQ1JTDQoNCmBgYHtyfQ0KYnJhemlsMCAlPiUgDQogIGdncGxvdCgpICsNCiAgZ2VvbV9zZihhZXMoKSkgDQpgYGANCg0KDQpgYGB7cn0NCmdncGxvdCgpICsNCiAgZ2VvbV9zZihhZXMoKSwgZGF0YSA9IGJyYXppbDApDQpgYGANCg0KYGBge3J9DQpnZ3Bsb3QoKSArDQogIGdlb21fc2YoYWVzKCksIGRhdGEgPSB1Y3NmaSkNCmBgYA0KDQojIyBIYXJtb25pemUgQ1JTDQoNCmBgYHtyfQ0KI2BzdF9jcnM8LWAodWNzZmkpDQpzdF9jcnModWNzZmkpDQpzdF9jcnMoYnJhemlsMCkNCmBgYA0KDQojIyMgSGFyZGNvZGUgdGhlIGNycw0KDQp3aXRoIHNvbWUgdmVyeSBmdW5reSBub3RhdGlvbg0KDQo+IFxgc3RfY3JzXGA8LSg0MzI2KQ0KDQpgYGB7cn0NCnVjc2ZpIDwtIHVjc2ZpICU+JSANCiAgYHN0X2NyczwtYCg0MzI2KQ0KYGBgDQoNCiMjIyBWZXJpZnkgQ1JTIEFzc2lnbm1lbnQNCg0KYGBge3J9DQojYHN0X2NyczwtYCh1Y3NmaSkNCnN0X2Nycyh1Y3NmaSkNCnN0X2NycyhicmF6aWwwKQ0KYGBgDQoNCiMjIFRFU1Qgd2l0aCBOZXcgQ1JTDQoNCk5vdGUgdGhlIHNhbWUgQ1JTIHJlcHJlc2VudGVkIGJ5IHRoZSBzYW1lIGxhdC9sb24NCg0KDQpgYGB7cn0NCmdncGxvdCgpICsNCiAgZ2VvbV9zZihhZXMoKSwgZGF0YSA9IHVjc2ZpKQ0KYGBgDQoNCg0KDQpgYGB7cn0NCmdncGxvdCgpICsNCiAgZ2VvbV9zZihhZXMoKSwgZGF0YSA9IGJyYXppbDApDQpgYGANCg0KIyMjIExheWVyIHRoZSBUd28gbWFwcw0KDQpgYGB7cn0NCmdncGxvdCgpICsNCiAgZ2VvbV9zZihhZXMoKSwgZGF0YSA9IGJyYXppbDApICsNCiAgZ2VvbV9zZihhZXMoZmlsbCA9IEdJRDcsIGNvbG9ycyA9IEdJRDcpLCBkYXRhID0gdWNzZmkpIA0KYGBgDQoNCiMjIENvbnZlcnQgYmFjayB0byBzcA0KDQpCZWNhdXNlIHlvdSBtaWdodCBwcmVmZXIgbWFwcGluZyBnZ3Bsb3QgdXNpbmcgZ2VvbV9wb2x5Z29uDQoNCg0KYGBge3J9DQpjbGFzcyh1Y3NmaSkNCmNsYXNzKGJyYXppbDApDQpgYGANCg0KIyMgQ29udmVydCBmcm9tIGBzZmAgdG8gYHNwYA0KDQpgYGB7cn0NCnVjX3NwIDwtIGFzKHVjc2ZpLCAiU3BhdGlhbCIpDQpiel9zcCA8LSBhcyh1Y3NmaSwgIlNwYXRpYWwiKQ0KYGBgDQoNCg0KYGBge3J9DQpjbGFzcyh1Y19zcCkNCmNsYXNzKGJ6X3NwKQ0KYGBgDQoNCiMjIFJlbW92ZSBMYXQvTG9uIExpbmVzDQoNCmBgYHtyfQ0KZ2dwbG90KCkgKw0KICBnZW9tX3NmKGFlcygpLCBkYXRhID0gYnJhemlsMCkgKw0KICBnZW9tX3NmKGFlcyhmaWxsID0gR0lENywgY29sb3JzID0gR0lENyksIGRhdGEgPSB1Y3NmaSkgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwgDQogICAgICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJ0cmFuc3BhcmVudCIpLCANCiAgICAgICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShjb2xvciA9ICJ0cmFuc3BhcmVudCIpLCANCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCksIA0KICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSwgDQogICAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCkpICsgDQogIGdndGl0bGUoIkNvb2xpbyBCcmF6aWwgTWFwIFRpdGxlIikgKyANCiAgeWxhYigiU291dGggdG8gTm9ydGgiKSANCmBgYA0KDQoNCiMjIFNhdmUgSXQNCg0KYGBge3J9DQpnZ3NhdmUoaGVyZSgib3V0ZmlsZSIsImNvb2xfbWFwLnBuZyIpLCANCiAgICAgICBwbG90ID0gbGFzdF9wbG90KCksDQogICAgICAgd2lkdGggPSAxMCwNCiAgICAgICBoZWlnaHQgPSAxMCwNCiAgICAgICB1bml0cyA9ICJjbSIpDQpgYGANCg0K